package fr.utbm.set.safeplatoon.common.merging.network;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.swing.event.EventListenerList;

import fr.utbm.set.safeplatoon.common.merging.data.listner.LmsListener;



public class ServerLMS implements Runnable{

	//Host IP
	 
	private Integer port;

 
	// Imput stream Data form Socket
	private DataInputStream entry;

	// Imput data from Socket
	private ArrayList<Double> values;

	// Data size
	private Integer size=180;


	private final EventListenerList listeners = new EventListenerList();


	protected ServerSocket    socketEcoute;
	protected Socket          socketService;
	protected InputStream     entreeSocket;
	protected OutputStream    sortieSocket;


	/**
	 * Creates a thread
	 * 
	 * @param host - the host name, or null for the loopback address.
	 * @param port - the port number
	 * @throws IOException 
	 */
	public ServerLMS( Integer port, Integer s) throws IOException {


		this.socketEcoute = new ServerSocket(port);
		System.out.println("Connexion sur "+this.socketEcoute);
		while (this.socketService==null) {

			this.socketService = this.socketEcoute.accept();
		}
		this.sortieSocket = this.socketService.getOutputStream();
		this.entreeSocket = this.socketService.getInputStream();
		this.entry = new DataInputStream(this.socketService.getInputStream());

	}



	//Data reception
	public void run() {
		while (true) {
			Thread.yield();
			ArrayList<Double> tmpValues = new ArrayList<Double>();


			try {

				if(entry!=null){

					double valeurMin = 20000;
					long accum = 0;
					double val = 0;

					for (int i = 0; i < this.size ; i++) {

						//
						accum = 0;
						for ( int shiftBy=0; shiftBy<64; shiftBy+=8 )
						{
							// must cast to long or the shift would be done modulo 32
							accum |= ( (long)( entry.readByte() & 0xff ) ) << shiftBy;
						}
						val = Double.longBitsToDouble(accum);


						if(i>1)
							tmpValues.add(  val/100);

						if(valeurMin>val) valeurMin = val;
					}

					this.values = tmpValues;
					this.fireData(this.values);
				}

			} catch (Exception e) {
				e.printStackTrace();
			}


		}
	}

	protected void fireData(ArrayList<Double> values2){
		System.out.println("LMSDATA "+values2);
		for(LmsListener listener : getLmsListeners()) {
			listener.setData(values2);
		}
	}

	public LmsListener[] getLmsListeners() {
		return listeners.getListeners(LmsListener.class);
	}

	public void addLmsListener(LmsListener listener) {
		listeners.add(LmsListener.class, listener);
	}

	public void removeLmsListener(LmsListener listener) {
		listeners.remove(LmsListener.class, listener);
	}


	/**
	 * Return the data from the data socket connexion
	 * 
	 * @return the data list from Socket 
	 */
	public ArrayList<Double> getData() {
		return new ArrayList<Double>(this.values);
	}
}